package org.project.task.util;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.JwtParser;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.security.Keys;

import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import java.nio.charset.StandardCharsets;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
import java.util.Date;
import java.util.Map;

public class JwtUtils {
    private static String signKey = generateHmacShaKey(256); // 使用256位密钥
    private static Long expire = 43200000L;

    private static String generateHmacShaKey(int keySizeInBits) {
        try {
            KeyGenerator keyGen = KeyGenerator.getInstance("HmacSHA256"); // 根据需要选择HmacSHA256/HmacSHA384/HmacSHA512
            keyGen.init(keySizeInBits);
            SecretKey secretKey = keyGen.generateKey();
            return Base64.getEncoder().encodeToString(secretKey.getEncoded());
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("Failed to generate HMAC-SHA key", e);
        }
    }

    /**
     * 生成JWT令牌
     * @param claims JWT第二部分负载 payload 中存储的内容
     * @return
     */
    public static String generateJwt(Map<String, Object> claims){
        // 生成 HMAC 密钥，根据提供的字节数组长度选择适当的 HMAC 算法，并返回相应的 SecretKey 对象。
        SecretKey key = Keys.hmacShaKeyFor(signKey.getBytes(StandardCharsets.UTF_8));
        // 生成JWT的时间
        long expMillis = System.currentTimeMillis() + expire;
        Date exp = new Date(expMillis);
        // 设置jwt的body
        return Jwts.builder()
                .addClaims(claims)
                .signWith(key) // 使用密钥进行签名
                .setExpiration(exp) // 设置过期时间
                .compact(); // 构建并生成JWT字符串
    }

    /**
     * Token解密
     * @param token 加密后的token
     * @return
     */
    public static Claims parseJWT(String token) {
        //生成 HMAC 密钥，根据提供的字节数组长度选择适当的 HMAC 算法，并返回相应的 SecretKey 对象。
        SecretKey key = Keys.hmacShaKeyFor(signKey.getBytes(StandardCharsets.UTF_8));
        // 得到DefaultJwtParser
        JwtParser jwtParser = Jwts.parser()
                // 设置签名的秘钥
                .verifyWith(key)
                .build();
        Jws<Claims> jws = jwtParser.parseSignedClaims(token);
        Claims claims = jws.getPayload();
        return claims;
    }
}